<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
    }
    #captcha {
      --width: 400px;
      --height: 260px;
      --puzzle-width: 80px;
      --puzzle-height: 80px;
      --moved: 0px;

      border-radius: 4px;
      background-image: url('./1.jpg');
      width: var(--width);
      height: var(--height);
      background-size: contain;
      background-position: center;
      background-repeat: no-repeat;
      position: relative;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    }
    #captcha::before, #captcha::after {
      position: absolute;
      content: '';
      display: block;
      width: inherit;
      height: inherit;
      /* background-color: red; */
      background-image: inherit;
      background-position: inherit;

      --a: calc( (var(--height) - var(--puzzle-height)) / 2 );
      --b: var(--puzzle-width);
      --c: calc( var(--width) - var(--puzzle-width) * 2 );

      clip-path: inset(var(--a) var(--b) var(--a) var(--c));
      -webkit-clip-path: inset(var(--a) var(--b) var(--a) var(--c));
    }
    #captcha::after {
      transform: translateX(clamp(
        calc( var(--width) * -1 ),
        calc( (var(--width) * -1) + var(--moved) ),
        calc( var(--puzzle-width) )
      ));
      transition: 0.24s all ease-in-out;
    }
    #captcha:active::after {
      transition: none;
    }
    #captcha::before {
      background-color: rgba(0, 0, 0, 0.6);
      background-blend-mode: multiply;
    }

    #handle {
      width: calc( var(--width) + var(--puzzle-width) * 2 );
      height: 30px;
      border-radius: 18px;
      background-color: #eee;
      position: absolute;
      bottom: -50px;
      left: calc( var(--puzzle-width) * 2 * -1 );
      box-shadow: inset 0px 0px 12px rgba(0, 0, 0, 0.2);
      border: 3px solid #ccc;
    }
    #handle span {
      display: block;
      width: calc( var(--puzzle-width) );
      height: inherit;
      border-radius: inherit;
      background-color: #fff;
      box-shadow: inset 0px 0px 6px rgba(0, 0, 0, 0.25), 0px 2px 4px rgba(0, 0, 0, 0.3);
      position: absolute;
      cursor: move;
      transform: translateX(clamp(0px, var(--moved), calc( var(--width) + var(--puzzle-width) )));
      transition: 0.24s all ease-in-out;
    }
    #captcha:active #handle span{
      transition: none;
    }
    #captcha.passed::before,
    #captcha.passed::after,
    #captcha.passed #handle {
      opacity: 0;
    }
  </style>
</head>
<body>
  <div id="captcha">
    <div id="handle"><span></span></div>
  </div>
  <script>
    let isMove = false;
    const oCaptha = document.querySelector('#captcha');
    const oHandle = oCaptha.querySelector('#handle');
    const oBtn = oHandle.querySelector('span');
    
    oBtn.addEventListener('mousedown', e => {
      isMove = true;
    })
    document.addEventListener('mousemove', e => {
      if (isMove) {
        const offsetLeft = oHandle.getBoundingClientRect().left;
        const btnWidth = oBtn.getBoundingClientRect().width;
        
        oCaptha.style.setProperty('--moved', `${e.clientX - offsetLeft - btnWidth / 2 }px`);

      }
    })
    document.addEventListener('mouseup', e => {
      if (isMove) {
        const finalOffset = e.clientX - oHandle.getBoundingClientRect().left;

        if (finalOffset >= 430 && finalOffset <= 450) {
          oCaptha.classList.add('passed')
        } else {
          oCaptha.style.setProperty('--moved', '0px');
          oCaptha.classList.remove('passed');
        }
        isMove = false;
      }
    })
  </script>
</body>
</html>
